fontchooser: Populate the list incrementally
authorMatthias Clasen <mclasen@redhat.com>
Tue, 25 Aug 2020 19:13:39 +0000 (15:13 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 25 Aug 2020 19:51:04 +0000 (15:51 -0400)
By adding 20 fonts / frame to the font list, we can
get the font chooser dialog to show up much faster.

This change gets the font chooser up in 265ms here.

gtk/gtkfontchooserwidget.c

index 480cd88d54b6c1097658ff0a20056b58ac5c39e6..43513163006f6780f1a3fd1f42c36fc4a23dfa67 100644 (file)
@@ -54,6 +54,7 @@
 #include "gtkroot.h"
 #include "gtkfilterlistmodel.h"
 #include "gtkflattenlistmodel.h"
+#include "gtkslicelistmodel.h"
 #include "gtkmaplistmodel.h"
 
 #include <hb-ot.h>
@@ -770,6 +771,40 @@ axis_free (gpointer v)
   g_free (a);
 }
 
+/* We incrementally populate our fontlist to prevent blocking
+ * the font chooser for a long time with expensive FcFontSort
+ * calls in pango for every row in the list).
+ */
+static gboolean
+add_to_fontlist (GtkWidget     *widget,
+                 GdkFrameClock *clock,
+                 gpointer       user_data)
+{
+  GtkFontChooserWidget *self = GTK_FONT_CHOOSER_WIDGET (widget);
+  GtkSliceListModel *model = user_data;
+  GListModel *child_model;
+  guint n;
+
+  if (gtk_filter_list_model_get_model (self->filter_model) != G_LIST_MODEL (model))
+    return G_SOURCE_REMOVE;
+
+  child_model = gtk_slice_list_model_get_model (model);
+
+  n = gtk_slice_list_model_get_size (model);
+
+  n += 10;
+
+  if (n >= g_list_model_get_n_items (child_model))
+    n = G_MAXUINT;
+
+  gtk_slice_list_model_set_size (model, n);
+
+  if (n == G_MAXUINT)
+    return G_SOURCE_REMOVE;
+  else
+    return G_SOURCE_CONTINUE;
+}
+
 static void
 update_fontlist (GtkFontChooserWidget *self)
 {
@@ -784,6 +819,10 @@ update_fontlist (GtkFontChooserWidget *self)
     model = g_object_ref (G_LIST_MODEL (fontmap));
   else
     model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (g_object_ref (fontmap))));
+
+  model = G_LIST_MODEL (gtk_slice_list_model_new (model, 0, 20));
+  gtk_widget_add_tick_callback (GTK_WIDGET (self), add_to_fontlist, g_object_ref (model), g_object_unref);
+
   gtk_filter_list_model_set_model (self->filter_model, model);
   g_object_unref (model);
 }